package com.plug.common.utils;

import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.MessageDigest;
import java.util.*;

/**
 * 验证辅助类
 *
 * @author Archx[archx@foxmail.com]
 * @date 2016/3/21 0021
 */
public final class ValidateUtils {

    private ValidateUtils() {
    }

    /**
     * 返回错误消息的Map
     *
     * @param result 验证结果
     * @return map
     */
    public static final Map<String, String> handle(BindingResult result) {
        Map<String, String> map = new HashMap<>();
        for (FieldError fieldError : result.getFieldErrors()) {
            map.put(fieldError.getField(), fieldError.getDefaultMessage());
        }
        return map;
    }

    /**
     * 方法参数验证错误处理
     *
     * @param cve 验证异常
     * @return set
     */
    public static final Set<String> handle(ConstraintViolationException cve) {
        Iterator<ConstraintViolation<?>> iterator = cve.getConstraintViolations().iterator();
        Set<String> set = new HashSet<>();
        while (iterator.hasNext()) {
            set.add(iterator.next().getMessage());
        }
        return set;
    }

    /**
     * 参数签名
     *
     * @param params 参数
     * @param secret 密钥
     * @return
     */
    public static final String signature(Map<String, String> params, String secret) {
        // 先将参数以其参数名的字典序升序进行排序
        Map<String, String> sortedParams = new TreeMap<String, String>(params);
        Set<Map.Entry<String, String>> entrys = sortedParams.entrySet();

        // 遍历排序后的字典，将所有参数按"key=value"格式拼接在一起
        StringBuilder builder = new StringBuilder();
        for (Map.Entry<String, String> param : entrys) {
            builder.append(param.getKey()).append("=").append(param.getValue());
        }
        builder.append(secret);
        // 使用MD5对待签名串求签
        byte[] bytes = null;
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            bytes = md5.digest(builder.toString().getBytes(Charset.forName("UTF-8")));
        } catch (GeneralSecurityException ex) {
            throw new IllegalArgumentException(ex);
        }

        // 将MD5输出的二进制结果转换为小写的十六进制
        StringBuilder sign = new StringBuilder();
        for (int i = 0; i < bytes.length; i++) {
            String hex = Integer.toHexString(bytes[i] & 0xFF);
            if (hex.length() == 1) {
                sign.append("0");
            }
            sign.append(hex);
        }
        return sign.toString();
    }
}
